package cn.com.cym.gamezao.service.impl;

import cn.com.cym.gamezao.base.BaseImpl;
import cn.com.cym.gamezao.base.BaseRepository;
import cn.com.cym.gamezao.base.SearchPage;
import cn.com.cym.gamezao.entity.LocalFile;
import cn.com.cym.gamezao.entity.single.LostFound;
import cn.com.cym.gamezao.repository.LocalFileRepository;
import cn.com.cym.gamezao.repository.single.LostFoundRepository;
import cn.com.cym.gamezao.service.LocalFileService;
import cn.com.cym.gamezao.util.CommonUtils;
import cn.hutool.core.util.ReflectUtil;
import lombok.SneakyThrows;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class LocalFileImpl extends BaseImpl<LocalFile> implements LocalFileService {

    final LocalFileRepository thisRepository;

    final LostFoundRepository lostFoundRepository;

    public LocalFileImpl(LocalFileRepository localFileRepository,LostFoundRepository lostFoundRepository){
        this.thisRepository=localFileRepository;
        this.lostFoundRepository = lostFoundRepository;
    }

    @Override
    public BaseRepository<LocalFile, Long> getJpaRepository() {
        return this.thisRepository;
    }

    @Override
    public Page<LocalFile> findByPageable(SearchPage searchPage) {
        String[] sortBy = searchPage.getSortBy().toArray(new String[searchPage.getSortBy().size()]);

        Pageable pageable = PageRequest.of(searchPage.getCurrent()-1, searchPage.getPageSize(), searchPage.getSort(), sortBy);

        Specification<LocalFile> specification = new Specification<>() {

            private static final long serialVersionUID = -2661077778894635593L;

            /**
             * @param root: 代表查询的实体类.
             * @param query: 可以从中可到 Root 对象, 即告知 JPA Criteria 查询要查询哪一个实体类. 还可以
             * 来添加查询条件, 还可以结合 EntityManager 对象得到最终查询的 TypedQuery 对象.
             * @param  cb: CriteriaBuilder 对象. 用于创建 Criteria 相关对象的工厂. 当然可以从中获取到 Predicate 对象
             * @return  Predicate 类型, 代表一个查询条件.
             */
            @SneakyThrows
            @Override
            public Predicate toPredicate(Root<LocalFile> root,
                                         CriteriaQuery<?> query, CriteriaBuilder cb) {
                final Map<String, Field> fieldMap = ReflectUtil.getFieldMap(LocalFile.class);
                return cb.and(CommonUtils.pageSet(fieldMap,searchPage,cb,root));
            }
        };
        return this.thisRepository.findAll(specification, pageable);
    }


    @Override
    public void deleteById(Long id) {
        this.thisRepository.deleteById(id);
    }

    @Override
    public LocalFile getByUuidName(String uuidName) {
        return this.thisRepository.getByUuidName(uuidName);
    }

    @Override
    public Boolean isWhite(String uuidName) {
        List<LostFound> allByFileRandomId = this.lostFoundRepository.findAllByFileRandomId(uuidName);
        return allByFileRandomId.size()>0;
    }
}
